import math
import random
import re

ORDER_BIG = 'big'
ORDER_LITTLE = 'little'


# 安全去除空格
def trim2empty(val: str) -> str:
    if not val:
        return ''
    else:
        return val.strip()


# 下划线连接转换成驼峰命名
def underline2camelize(underline_str: str):
    ret = re.sub(r'(_\w)', lambda x: x.group(1)[1].upper(), underline_str)
    return ret


# 随机生成字节
def random_byte():
    return random.randint(0, 255).to_bytes(1, 'big')[0]


def random_bytearray(length):
    data = bytearray(length)
    for i in range(0, length):
        data[i] = random_byte()


# 字节数组转换成十六进制数据
def bytes2hex(src: bytes, lw=0):
    r = " ".join(["{:02x}".format(x).upper() for x in src])
    if lw <= 0:
        return r
    else:
        return r.ljust(lw * 3)


def bytes2ascii(src: bytes):
    return src.decode('ascii', 'ignore')


def bytes_view(src: bytes, lw=16):
    size = len(src)
    lines = math.ceil(size / lw)
    line_arr = []
    for l in range(0, lines):
        line_arr.append(_to_line(l, src[l * lw: l * lw + lw], lw))

    return '\n'.join(line_arr)


def _to_line(l: int, src: bytes, lw):
    ln_arr = (l * lw).to_bytes(2, byteorder=ORDER_BIG)
    ln = "".join(["{:02x}".format(x).upper() for x in ln_arr])

    export = '%s: %-s    %s' % (ln, bytes2hex(src, lw), _to_ascii(src))
    return export


def _to_ascii(src: bytes):
    arr = []
    for b in src:
        if b < 0x20 or b >= 0x7F:
            arr.append('.')
        else:
            arr.append(bytes2ascii(b.to_bytes(1, ORDER_BIG)))
    return ''.join(arr)


def byte2ascii(src: bytes):
    return src.encode('ascii')


def hex2bytes(src: str):
    ba = bytes.fromhex(src)
    return ba


def dump_map(cmap, sep='\n'):
    clist = []
    for index, key in enumerate(cmap):
        line = '%s: %s' % (key, str(cmap[key]))
        clist.append(line)

    return sep.join(clist)


def int2byte(val):
    return val.to_bytes(1, 'big')[0]


def byte2int(val):
    return int(val)


def ip2bytes(ip: str):
    segs = ip.split('.')

    if segs.__len__() != 4:
        raise AssertionError('Not a valid ip.')

    ba = bytearray(4)
    ba[0] = int2byte(int(segs[0]))
    ba[1] = int2byte(int(segs[1]))
    ba[2] = int2byte(int(segs[2]))
    ba[3] = int2byte(int(segs[3]))
    return ba


def bytes2ip(src: bytes):
    return '%d.%d.%d.%d' % (int(src[0]), int(src[1]), int(src[2]), int(src[3]))


# 解析一行数据
def parse_line(line, sep):
    if not line:
        return None, None

    if not sep:
        sep = ':'

    pos = line.find(sep)

    if pos > 0:
        key = line[0:pos].strip()
        value = line[pos + 1:].strip()

        return key, value

    return None, None
